package com.enjoyor.soa.traffic.frame.support.file.impl;

import com.enjoyor.soa.traffic.frame.properties.FileHanderProperties;
import com.enjoyor.soa.traffic.frame.support.file.IFilesTool;
import com.enjoyor.soa.traffic.util.enums.EnumAppCode;
import com.enjoyor.soa.traffic.util.exception.ManagerException;
import com.enjoyor.soa.traffic.util.helper.ResultHelper;
import com.enjoyor.soa.traffic.util.helper.TimeHelper;
import com.enjoyor.soa.traffic.util.pojo.ResultPojo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Service
@SuppressWarnings("restriction")
@EnableConfigurationProperties({FileHanderProperties.class})
public class FilesTool implements IFilesTool {

    @Autowired
    private FileHanderProperties fileHanderProperties;

    @Override
    public ResultPojo fileUpload(MultipartFile file) {
        return fileUpload(file, TimeHelper.dateToString(new Date(), "yyyyMMdd"), this.makeNewFileName(file));
    }

    @Override
    public ResultPojo fileUpload(MultipartFile file, String secondFilePath) {
        return fileUpload(file, secondFilePath, this.makeNewFileName(file));
    }

    @Override
    public ResultPojo fileUpload(MultipartFile file, String secondFilePath, String fileNewName) {
        if (file.isEmpty())
            throw new ManagerException("上传文件不能为空！");
        ResultPojo resultPojo = new ResultPojo();
        try {
            // 原文件名
            String fileName = file.getOriginalFilename();
            Map<String, String> map = new HashMap<String, String>();
            map.put("fileOldName", fileName);
            if (!fileHanderProperties.isValidFile(fileName, fileHanderProperties.getSuffixsArray()))
                throw new ManagerException(String.format("文件不合法,文件名:{%s}!", new Object[]{fileName}));

            // 上传服务器文件夹
            String filePath = fileHanderProperties.getFileDir();

            // 文件存储磁盘地址
            String path = filePath + "/" + secondFilePath + "/" + fileNewName;

            File dest = new File(path);

            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
            file.transferTo(dest);

            // 映射地址
            String mappingAddress = fileHanderProperties.getMappingAddress(secondFilePath, fileNewName);

            map.put("mappingAddress", mappingAddress);
            map.put("secondDir", secondFilePath);
            map.put("fileName", fileNewName);
            resultPojo.setResultList(map);
        } catch (Exception e) {
            throw new ManagerException(e.getMessage());
        }
        return resultPojo;
    }

   
    @Override
    public ResultPojo fileUploadBase64(String base64Data, String secondFilePath) {
        String dataPrix = "";
        String data = "";
        String suffix = "";
        if (base64Data == null || "".equals(base64Data)) {
            return ResultHelper.getResult(EnumAppCode.PARAM_NULL);
        } else {
            String[] d = base64Data.split("base64,");
            if (d != null && d.length == 2) {
                dataPrix = d[0];
                data = d[1];
            } else {
                return ResultHelper.getResult(EnumAppCode.IMAGE_ERROR);
            }
        }
        if ("data:image/jpeg;".equalsIgnoreCase(dataPrix)) {//编码的jpeg图片数据
            suffix = ".jpg";
        } else if ("data:image/x-icon;".equalsIgnoreCase(dataPrix)) {//编码的icon图片数据
            suffix = ".ico";
        } else if ("data:image/gif;".equalsIgnoreCase(dataPrix)) {//编码的gif图片数据
            suffix = ".gif";
        } else if ("data:image/png;".equalsIgnoreCase(dataPrix)) {//编码的png图片数据
            suffix = ".png";
        } else {
            return ResultHelper.getResult(EnumAppCode.PARAM_FMT_ERROR);
        }
        String fileName = TimeHelper.dateToString(new Date(), "yyyyMMddHHmmssSS") + suffix;
        // 上传服务器文件夹
        String filePath = fileHanderProperties.getFileDir();
        String path = filePath + "/" + secondFilePath + "/" + fileName;
        
        File dest = new File(path);

        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        
        
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // 解密
            byte[] b = decoder.decodeBuffer(data);
            // 处理数据
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {
                    b[i] += 1024;
                }
            }
            OutputStream out = new FileOutputStream(path);
            out.write(b);
            out.flush();
            out.close();
            Map<String, String> map = new HashMap<String, String>();
            // 映射地址
            String mappingAddress = fileHanderProperties.getMappingAddress(secondFilePath, fileName);
            map.put("mappingAddress", mappingAddress);
            map.put("secondDir", secondFilePath);
            map.put("fileName", fileName);
            return ResultHelper.getResult(map);
        } catch (Exception e) {       
            return ResultHelper.getResult(e);
        }
    }

    @Override
    public ResultPojo removeFile(String secondDir, String fileName) {
        if (fileName == null || StringUtils.isBlank(fileName))
            throw new ManagerException("文件名不能为空！");
        String fileDir = fileHanderProperties.getFileDir();
        String fullPath = fileDir + "//" + secondDir + "//" + fileName;
        File file = new File(fullPath);
        if (file.exists() && file.isFile())
            return new ResultPojo(file.delete());
        else
            throw new ManagerException(String.format("文件删除失败,文件{%s}不存在!", new Object[]{fileName}));
    }

    /**
     *
     */
    @Override
    public void downloadFile(String secondDir, String fileName, HttpServletResponse response) {
        if (fileName == null || StringUtils.isBlank(fileName))
            throw new ManagerException("文件名不能为空！");
        if (secondDir == null || StringUtils.isBlank(secondDir))
            throw new ManagerException("二级目录不能为空！");
        String fullPath = fileHanderProperties.getFileDir() + "//" + secondDir + "//" + fileName;
        File file = new File(fullPath);
        if (file.exists() && file.isFile()) {
            // 处理中文名乱码问题
            try {
                fileName = new String(fileName.getBytes("GB2312"), "ISO_8859_1");
            } catch (UnsupportedEncodingException e) {
            }
            response.reset();
            // 设置强制下载不打开
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                OutputStream os = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = bis.read(buffer);
                }

            } catch (Exception e) {
                throw new ManagerException(e.getMessage());
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

    }

    protected String makeNewFileName(MultipartFile file) {

        // 原文件名
        String fileName = file.getOriginalFilename();
        // 文件名（没有后缀）
        String preName = fileName.substring(0, fileName.lastIndexOf("."));
        // 后缀名
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        // 新文件名
        String fileNewName = preName + "(" + TimeHelper.dateToString(new Date(), "yyyyMMddHHmmssSS") + ")" + suffixName;

        return fileNewName;

    }

}
